package cn.mw.cmdb.trigger;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.mw.cmdb.entity.*;
import cn.mw.cmdb.mongoMapper.MwCmdbTriggerMapper;
import cn.mw.cmdb.trigger.service.MwCmdbTriggerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.Map;

@Slf4j
public class StringSingleFieldTrigger implements RecordTrigger<String ,MwCmdbTrigger>{

    private PropertyInfo propertyInfo;

    private MwCmdbNotify mwCmdbNotify;

    private MwCmdbTriggerMapper mwCmdbTriggerMapper;

    private ModelInfoFilterPropertyId modelInfoFilterPropertyId;

    public StringSingleFieldTrigger(PropertyInfo propertyInfo ,MwCmdbNotify mwCmdbNotify
            ,MwCmdbTriggerMapper mwCmdbTriggerMapper ,ModelInfoFilterPropertyId modelInfoFilterPropertyId){
        this.propertyInfo = propertyInfo;
        this.mwCmdbNotify = mwCmdbNotify;
        this.mwCmdbTriggerMapper = mwCmdbTriggerMapper;
        this.modelInfoFilterPropertyId = modelInfoFilterPropertyId;
    }

    @Override
    public boolean match(String value) {
        PropertyTypeRef propertyTypeRef = propertyInfo.getPropertyTypeRef();
        //1.只有设置时间过期才启用触发器
        if(propertyInfo.getPropertyType().getClass().isAssignableFrom(PropertyTypeTime.class)
                && null != propertyTypeRef.getContext()){
            Object enableObj = propertyTypeRef.getContext().get(TriggerConstants.EnableExpireTimeKey);
            if(null != enableObj){
                Boolean enable = (Boolean) enableObj;
                if(enable){
                    return true;
                }
            }
        }

        return false;
    }

    @Override
    public MwCmdbTrigger getTrigger(TriggerContext triggerContext) {
        MwCmdbTrigger mwCmdbTrigger = MwCmdbTrigger.builder()
                .triggerType(RecordTrigger.class.getSimpleName())
                .bussinessType(triggerContext.getType().name())
                .bussinessId(triggerContext.getTypeId())
                .build();

        ModelInfo modelInfo = triggerContext.getModelInfo();
        if(null != modelInfo){
            mwCmdbTrigger.setGroupPath(modelInfo.getGroupPath());
            mwCmdbTrigger.setModelName(modelInfo.getModelName());
            String fieldName = modelInfo.convertModelPropertyKeyMapWithInstancePrefix(propertyInfo.getId() ,modelInfoFilterPropertyId);
            mwCmdbTrigger.setFieldName(fieldName);
        }

        //计算触发日期
        InstanceInfo instanceInfo = triggerContext.getInstanceInfo();
        if(null == instanceInfo){
            log.warn("instanceInfo is null!");
            return null;
        }
        mwCmdbTrigger.setBussinessName(instanceInfo.getInstanceName());
        Map data = BeanUtil.beanToMap(instanceInfo, false ,true);
        mwCmdbTrigger.setData(data);
        //先获取指定字段,再获取属性名的字段
        PropertyTypeRef propertyTypeRef = propertyInfo.getPropertyTypeRef();
        mwCmdbTrigger.setFieldDesc(propertyInfo.getDesc());

        Object dateObj = instanceInfo.getValue(propertyInfo.getId());
        if(null == dateObj){
            dateObj = instanceInfo.getValue(propertyInfo.getName());
            if(null == dateObj){
                log.warn("instanceInfo get no date infomation!");
                return null;
            }
        }
        //如果配置字段无法获取,则需要判断该字段是否启用到期提醒
        Boolean enableExpireTime = propertyTypeRef.getValue(TriggerConstants.EnableExpireTimeKey, Boolean.class);
        if (null == enableExpireTime || !enableExpireTime) {
            return null;
        }


        if(!(dateObj instanceof Date)){
            log.warn("data is not date!");
            return null;
        }

        //优先使用字段的值,如果不存在,则获取默认值
        Date validateDate = (Date) dateObj;
        Date trigDate = null;
        String beforeNum = propertyTypeRef.getValue(TriggerConstants.BeforeNumKey);
        Integer num = null;
        String unit = null;
        if(StringUtils.hasText(beforeNum)){
            num = 0 - Integer.parseInt(beforeNum);
            unit = propertyTypeRef.getValue(TriggerConstants.UnitKey);
        }else{
            //如果匹配的个数只有一个才能使用默认配置
            num = 0 - mwCmdbNotify.getBeforeNum();
            unit = mwCmdbNotify.getUnit().name();
        }

        PropertyTypeTimeUnit ops = PropertyTypeTimeUnit.valueOf(unit);
        switch (ops){
            case min -> trigDate = DateUtil.offsetMinute(validateDate ,num);
            case hour -> trigDate = DateUtil.offsetHour(validateDate ,num);
            case day -> trigDate = DateUtil.offsetDay(validateDate ,num);
            case month -> trigDate = DateUtil.offsetMonth(validateDate ,num);
        }
        mwCmdbTrigger.setTrigDate(trigDate);
        mwCmdbTrigger.setModelGroupId(instanceInfo.getGroupId());
        mwCmdbTrigger.setModelId(instanceInfo.getModelId());
        return mwCmdbTrigger;
    }

    @Override
    public void addTrigger(TriggerContext triggerContext) {
        MwCmdbTrigger mwCmdbTrigger = getTrigger(triggerContext);
        if(null != mwCmdbTrigger){
            mwCmdbTriggerMapper.insert(mwCmdbTrigger);
        }
    }
}
